<?php


namespace app\msgapi\service;

use app\msgapi\model\{CueventLog, Cust, System, User, UserCust};
use app\utils\Date;
use think\facade\Db;
use think\facade\Log;
error_reporting(E_ERROR | E_PARSE);
class HuihuaCustService
{
    private Cust $custModel;
    private User $userModel;
    private UserCust $userCustModel;

    public function __construct(Cust $custModel, User $userModel, UserCust $userCustModel)
    {
        $this->custModel = $custModel;
        $this->userModel = $userModel;
        $this->userCustModel = $userCustModel;
    }

    /**获取客户列表
     * @param $data
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function getCustLst($data,$admin_groupid,$adminid)
    {
        //有权限的所有成员
        $auth_user_arr = HsorganizationService::getDepartmentLst(2,0,$admin_groupid,$adminid);
        if(($auth_user_arr !== 'all') && empty($auth_user_arr)) return error_json('暂无成员权限');
        //成员权限
        if($data['uid']){
            $uid = User::where('userid','=',$data['uid'])->value('id');
            $where[] = ['uid', '=', $uid];
        } else{
            if(($auth_user_arr !== 'all') && !empty($auth_user_arr) ){
                $uids = User::where('userid','in',$auth_user_arr)->column('id');
                $where[] = ['uid', 'in', $uids];
            }
        }
        $limit = $data['limit']?:config('page.defaule_limit');
        $data['type'] && $where[] = ['type', '=', $data['type']];
        $data['remark'] && $where[] = ['remark', 'like', "%{$data['remark']}%"];
        $data['keyword'] && $haswhere[] = ['name', 'like', "%{$data['keyword']}%"];
        $data['corpname'] && $haswhere[] = ['corp_name|corp_full_name', 'like', "%{$data['corpname']}%"];
        $list = UserCust::hasWhere('cust', function ($query) use ($haswhere) {
            $query->where($haswhere);
        });
        $list->with(['user', 'cust']);
        $list = $list->where($where)->paginate($limit)->toArray();
        return success_json('成功',$list);
    }

    /**查看客户详情
     * @param $data
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getCustDetail($data)
    {
        $external_uid = $data['external_uid'];
        $info = [];
        $info['cust_info'] = $this->custModel->findOrEmpty($external_uid)->toArray(); //客户信息
        $info['userlist'] = $this->userCustModel->with('user')->where('external_uid',$external_uid)->select()->toArray(); //客户关联成员列表信息
        $info['grouplist'] = HuihuaGroupChatService::getGroupList(); //客户所在群组列表信息
        return success_json('成功', $info);
    }


    /**主要解决一对一聊天中，获取外部联系人信息，如不存在外部联系人，则不去获取，根据请求的用户id到user表中检索
     * @param int $c_id
     * @param string $form
     * @param array|null $list
     * @param int $updateflag
     * @return array|false
     * @throws \think\Exception
     */
    public function queryExternalInfo(string $form, array $list = null, int $updateflag = 0)
    {
        if ($list) {
            $userlist = array_merge([$form], $list);
            $innerUser = $this->userModel->where('userid', 'in', $userlist)->column('userid');
            $diff = array_diff($userlist, $innerUser);
            if (count($diff) == 1) {
                $diff = array_values($diff);
                return $this->getExternalInfo($diff[0], $updateflag);
            }
            return false;
        }
        return false;

    }

    /** 获取外部联系人信息
     * @param string $external_userid 外部联系人id
     * @param int $updateflag 是否跟新
     * @return array|false
     * @throws \think\Exception
     */
    public function getExternalInfo(string $external_userid, int $updateflag = 0)
    {
        //群组信息也存在，直接返回相关信息
        $userInfoDb = $this->custModel->where('external_userid', $external_userid)->findOrEmpty()->toArray();
        if ($userInfoDb && $updateflag == 0) return $userInfoDb;
        $corpSelf = new WeworkCorpSelfService();
        $userInfo = $corpSelf->getExternalUserInfo($external_userid);
        if ($userInfo['errcode'] == 0) {
            $userInfo = [
                'external_userid' => $userInfo['external_contact']['external_userid'],
                'name' => $userInfo['external_contact']['name'],
                'position' => $userInfo['external_contact']['position'],
                'avatar' => $userInfo['external_contact']['avatar'],
                'corp_name' => $userInfo['external_contact']['corp_name'],
                'corp_full_name' => $userInfo['external_contact']['corp_full_name'],
                'type' => $userInfo['external_contact']['type'],
                'gender' => $userInfo['external_contact']['gender'],
                'external_profile' => $userInfo['external_contact']['external_profile'],
            ];
        } else {
            $userInfo = [
                'external_userid' => $external_userid,
                'special' => 1//是特殊对象
            ];
        }
        if ($userInfo) {
            try {
                $userInfoDb ? $this->custModel::update($userInfo, ['id' => $userInfoDb['id']]) : $this->custModel::create($userInfo);
                return $userInfo;
            } catch (\Exception $e) {
                Log::write('客户信息存储失败' . $e->getMessage());
            }
        }
        return false;
    }

    /**获取年度数据按照周分组
     * @param $data
     * @return mixed
     */
    public static function getYearData($data){
        $year = $data['year'] ?? date('Y');
        $where[] = ['createtime','between',[strtotime($year.'-01-01 00:00:00'),strtotime($year.'-12-31 23:59:59')]];
        $list = UserCust::field("WEEK(FROM_UNIXTIME(createtime,'%Y%m%d')) as week,count(id) as count")
            ->where($where)
            ->group("WEEK(FROM_UNIXTIME(createtime,'%Y%m%d'))")
            ->select()->order('createtime asc')->toArray();
        return $list;
    }

    /**根据用户和时间获取新增客户数即客户总数
     * @return array
     */
    public static function getBaseData($data)
    {
        $time_type = $data['time_type'] ?: 1;
        $time_type = strtotime(date('Y-m-d 00:00:00', strtotime("-{$time_type} days")));
        if($data['start_time']) $data['start_time'] = date('Y-m-d',strtotime($data['start_time'])) . ' 00:00:00';
        if($data['end_time']) $data['end_time'] = date('Y-m-d',strtotime($data['end_time'])) . ' 23:59:59';
        $userid = User::where('userid','=',$data['userid'])->value('id');
        //新增客户数
        $cust_add = Cust::alias('cust')
            ->join('user_cust uc', 'uc.external_uid = cust.id');
        if ($userid) {
            $cust_add = $cust_add->where('uc.uid', '=', $userid);
        }
        if ($data['start_time'] && $data['end_time']) {
            $cust_add = $cust_add->whereTime('uc.createtime', 'between', [strtotime(trim($data['start_time'])), strtotime(trim($data['end_time']))]);
        } else {
//            $cust_add = $cust_add->whereTime('uc.createtime', $time_type);
            $bgtime = date('Y-m-d 00:00:00', strtotime('+1 days', $time_type));
            $endtime = date('Y-m-d H:i:s');
            $cust_add = $cust_add->whereTime('uc.createtime', 'between', [strtotime(trim($bgtime)), strtotime(trim($endtime))]);
        }
        $cust_add = $cust_add->group('cust.id')->count();
        //客户总数
        $cust_total = Cust::alias('cust')
            ->join('user_cust uc', 'uc.external_uid = cust.id');
        if ($userid) {
            $cust_total = $cust_total->where('uc.uid', '=', $userid);
        }
        $cust_total = $cust_total->group('cust.id')->count();
        return compact('cust_add', 'cust_total');
    }

    /**根据成员和时间获取客户数据折线图
     * @return array|false
     */
    public static function getEchatsData($data)
    {
        $time_type = $data['time_type'] ?: 1;
        $time_type = strtotime(date('Y-m-d 00:00:00', strtotime("-$time_type days")));
        if($data['start_time']) $data['start_time'] = date('Y-m-d',strtotime($data['start_time'])) . ' 00:00:00';
        if($data['end_time']) $data['end_time'] = date('Y-m-d',strtotime($data['end_time'])) . ' 23:59:59';
        $userid = User::where('userid','=',$data['userid'])->value('id');
        //新增客户数
        $cust_add = Cust::field('FROM_UNIXTIME(uc.createtime,"%Y%m%d") as add_time,COUNT(cust.id) as count')
            ->alias('cust')
            ->join('user_cust uc', 'uc.external_uid = cust.id');
        if ($userid) {
            $cust_add = $cust_add->where('uc.uid', '=', $userid);
        }
        if ($data['start_time'] && $data['end_time']) {
            $cust_add = $cust_add->whereTime('uc.createtime', 'between', [strtotime(trim($data['start_time'])), strtotime(trim($data['end_time']))]);
            $bgtime = $data['start_time'];
            $endtime =  $data['end_time'];
        } else {
//            $cust_add = $cust_add->whereTime('uc.createtime', $time_type);
            $bgtime = date('Y-m-d 00:00:00', strtotime('+1 days', $time_type));
            $endtime = date('Y-m-d H:i:s');
            $cust_add = $cust_add->whereTime('uc.createtime', 'between', [strtotime(trim($bgtime)), strtotime(trim($endtime))]);
        }
        $cust_add = $cust_add->group('add_time')->select()->toArray();

        $cust_add = array_column($cust_add, 'count', 'add_time');
        $cust_add = Date::getChatDateList($bgtime, $endtime, $cust_add);

        return $cust_add;
    }

    /**获取流失客户列表
     * @param $data
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function getLostCustomers($data,$admin_groupid,$adminid)
    {
        //有权限的所有成员
        $auth_user_arr = HsorganizationService::getDepartmentLst(2,0,$admin_groupid,$adminid);
        if(($auth_user_arr !== 'all') && empty($auth_user_arr)) return error_json('暂无成员权限');
        //成员权限
        if($data['uid']){
            $uid = User::where('userid','=',$data['uid'])->value('id');
            $where[] = ['uid', '=', $uid];
        } else{
            if(($auth_user_arr !== 'all') && !empty($auth_user_arr) ){
                $uids = User::where('userid','in',$auth_user_arr)->column('id');
                $where[] = ['uid', 'in', $uids];
            }
        }
        $limit = $data['limit']?:config('page.defaule_limit');
        $data['type'] && $where[] = ['type', '=', $data['type']];
        $data['delete_type'] && $where[] = ['delete_type', '=', $data['delete_type']];
        $data['remark'] && $where[] = ['remark', 'like', "%{$data['remark']}%"];
        $data['keyword'] && $haswhere[] = ['name', 'like', "%{$data['keyword']}%"];
        $data['corpname'] && $haswhere[] = ['corp_name|corp_full_name', 'like', "%{$data['corpname']}%"];
        $list = UserCust::onlyTrashed(true)->hasWhere('cust', function ($query) use ($haswhere) {
            $query->where($haswhere);
        });
        $list->with(['user', 'cust']);
        $list = $list->where($where)->paginate($limit)->toArray();
        return success_json('成功',$list);
    }

    //****************************↓回调用↓******************************

    /**外部联系人免验证添加成员事件 || 添加企业客户事件 || 编辑客户事件
     * @param $UserID
     * @param $ExternalUserID
     * @throws \think\Exception
     */
    public static function add_customer($UserID,$ExternalUserID){
        //todo...此处可做欢迎语
        $wework = new WeworkCorpSelfService();
        $cust_info = $wework->getExternalUserInfo($ExternalUserID);
        if($cust_info['errcode'] !== 0){
            Log::write('[回调]客户信息获取失败,原因:'.$cust_info['errmsg'].'错误码:'.$cust_info['errcode']);
            throw new \think\Exception('客户信息请求出错', $cust_info['errcode']);
        }

//        Log::write(json_encode($cust_info),'info');
        $cust = new Cust(); $user_cust = new UserCust();
        $data = [
            'external_userid'=>$cust_info['external_contact']['external_userid'],
            'name'=>$cust_info['external_contact']['name'],
            'position'=>$cust_info['external_contact']['position'],
            'type'=>$cust_info['external_contact']['type'],
            'gender'=>$cust_info['external_contact']['gender'],
            'avatar'=>$cust_info['external_contact']['avatar'],
            'corp_name'=>$cust_info['external_contact']['corp_name'],
            'corp_full_name'=>$cust_info['external_contact']['corp_full_name']
        ];
        try {
            if($cust->where('external_userid','=',$ExternalUserID)->count() > 0){
                $cust->update(['external_userid'=>$ExternalUserID],$data);
                Log::write('[回调]客户更新成功','info');
            }else{
                $cust->create($data);
                Log::write('[回调]客户新增成功','info');
            }
            foreach ($cust_info['follow_user'] as $v){
                $db_user_cust = $user_cust->alias('a')
                    ->join('user b','a.uid = b.id','left')
                    ->join('cust c','a.external_uid = c.id','left')->field('a.*')
                    ->where([
                        'b.userid'=>$v['userid'],
                        'c.external_userid'=>$cust_info['external_contact']['external_userid']])->find();
                $user_cust_data = [
                    'remark'=>$v['remark'],
                    'description'=>$v['description'],
                    'createtime'=>$v['createtime'],
                ];
                if($db_user_cust){
                    $user_cust_data['id'] = $db_user_cust['id'];
                    $user_cust_data['uid'] = $db_user_cust['uid'];
                    $user_cust_data['external_uid'] = $db_user_cust['external_uid'];
                    $update_data[] = $user_cust_data;
                }else{
                    $user_cust_data['uid'] = User::where('userid','=',$v['userid'])->value('id');
                    $user_cust_data['external_uid'] = Cust::where('external_userid','=',$cust_info['external_contact']['external_userid'])->value('id');
                    if($user_cust_data['uid'] && $user_cust_data['external_uid']){
                        $save_data[] = $user_cust_data;
                    }else{
                        Log::write('[回调]客户或成员不存在,本条信息将不被保存','waring');
                    }
                }
            }
            if($save_data){
                $user_cust->saveAll($save_data);
                Log::write('[回调]客户关联成员保存成功','info');
            }
            if($update_data){
                $user_cust->saveAll($update_data);
                Log::write('[回调]客户关联成员更新成功','info');
            }
        }catch (\Exception $e){
            Log::write('[回调]客户回调操作失败,错误原因:'.$e->getMessage().'行号:'.$e->getLine(),'error');
            throw new \think\Exception('客户回调操作失败',$cust_info['errcode']);
        }

    }

    /**删除企业客户事件 || 删除跟进成员事件
     * @param $UserID
     * @param $ExternalUserID
     * @return bool
     */
    public static function detele_cust($UserID,$ExternalUserID,$ChangeType){
        $user_cust = new UserCust();
        $db_user_cust = $user_cust->alias('a')
            ->join('user b','a.uid = b.id','left')
            ->join('cust c','a.external_uid = c.id','left')->field('a.*,b.userid,b.name as user_name,b.department_list,b.main_department,c.external_userid,c.name as cust_name')
            ->where(['b.userid'=>$UserID,'c.external_userid'=>$ExternalUserID])->find()->toArray();
        if(!$db_user_cust){
            Log::write('[回调]客户删除失败,客户不存在','error');
            return false;
        }else{
            $user_cust::update(['delete_type'=>$ChangeType],['id'=>$db_user_cust['id']]);
            $user_cust::destroy(['id'=>$db_user_cust['id']],false);
            @HuihuaSensitiveService::sendDeletionReminder($db_user_cust,$ChangeType); //删人通知
            Log::write('[回调]客户删除成功','info');
            return true;
        }
    }
    //****************************↑回调用↑******************************

    //*************************定时任务监控用***************

    //成员删除客户,账号禁用监控
    public static function AccountDisableMonitor()
    {
        //查询系统配置
        $delete_cust_config = System::getSys('delete_cust_config');
        if(!isset($delete_cust_config['forbidden']) || !(int)$delete_cust_config['forbidden']){
            Log::write('[删人账号禁用]监控未启用','info');
            return true;
        }
        $where = []; $start_time = intval(time() - (60 * $delete_cust_config['time'])); $end_time = time();
        $where[] = ['CreateTime','between',[$start_time,$end_time]];
        $where[] = ['ChangeType','=','del_external_contact'];
        $where[] = ['Source','<>','DELETE_BY_TRANSFER'];
        $where[] = ['is_ignore','=',0];
        $wherecopy = $where;
        $where[] = ['UserID','not in',$delete_cust_config['whiteList']];
        $group_info = CueventLog::where($where)->field('UserID, count(UserID) as count_num')->group('UserID')->having("count_num >= {$delete_cust_config['deleteNum']}")->select()->toArray();
        $weWorkCorpSelfService = new WeworkCorpSelfService();
        foreach ($group_info as $v){
            Db::startTrans();
            try{
                $tmp_res = $weWorkCorpSelfService->editUser(['userid'=>$v['UserID'],'enable'=>0]);
                if($tmp_res && $tmp_res['errcode'] == 0){
                    CueventLog::where($wherecopy)->where([['UserID','=',$v['UserID']]])->update(['is_ignore'=>1]); //禁用企微账号
                    User::update(['status'=>2],['userid'=>$v['UserID']]); //更新成员表
                    //可继续开发同时禁用会话存档平台账号
                    Log::write('[删人账号禁用]禁用成功','info');
                }else{
                    Log::write('[删人账号禁用]禁用失败,原因:'.$tmp_res['errmsg'],'error');
                    Db::rollback();
                }
                Db::commit();
                return true;
            }catch (\Exception $e){
                    Log::write('[删人账号禁用]禁用失败,原因:'.$e->getMessage(),'error');
                    Db::rollback();
            }
        }
        return true;
    }

    //*************************定时任务监控用***************

}